(display "\n========================================\n")
; 通用误差宏
(define tolerance 0.00001)

; 不改改进求平方根
(define (sqrt x)
    (define (sqrt-iter guess x)
        (define (good-enough? a b)
            (< (abs (- (square a) b)) tolerance))
        (define (improve guess x)
            (define (average a b)
                (/ (+ a b) 2))
            (average guess (/ x guess)))
        (if (good-enough? guess x)
            guess
            (sqrt-iter (improve guess x) x)))
    (sqrt-iter 1.0 x))
(display (sqrt 2))
(newline)

; (define (sqrt x)
;     (define (iter guess)
;         (define (good-enough? a b)
;             (< (abs (- (square a) b)) tolerance))
;         (define (improve guess)
;             (define (average a b)
;                 (/ (+ a b) 2))
;             (average guess (/ x guess)))
;         (if (good-enough? guess x)
;             guess
;             (iter (improve guess))))
;     (iter 1.0))

; (display (sqrt 2))
; (newline)

; 求不动点
(define (fix-point f first-guess)
    (define (good-enough? a b)
        (< (abs (- a b)) tolerance))
    (define (iter guess)
        (let ((next (f guess)))
            (if (good-enough? next guess)
                next
                (iter next))))
    (iter first-guess))
(display (fix-point cos 1.0))
(newline)

; 判断、改进，通用过程
(define (iterative-improve good-enough? improve)
    (lambda (first-guess)
        (define (try guess)
            (let ((next (improve guess)))
                (if (good-enough? next guess)
                    next
                    (try next))))
        (try first-guess)))

; 使用通用过程求平方根
(define (sqrt x)
    (define (good-enough? a b)
        (< (abs (- a b)) tolerance))
    (define (improve guess)
        (define (average a b)
            (/ (+ a b) 2))
        (average guess (/ x guess)))
    ((iterative-improve good-enough? improve) 1.0))
(display (sqrt 2))
(newline)

; 使用通用过程实现求不动点
(define (fix-point f first-guess)
    (define (good-enough? a b)
        (< (abs (- a b)) tolerance))
    ((iterative-improve good-enough? f) first-guess))
(display (fix-point cos 1.0))
(newline)

(display "\n========================================\n")

